#include <bits/stdc++.h>
using namespace std;

/*
1123. 最深叶节点的最近公共祖先
已解答
中等
相关标签
相关企业
提示
给你一个有根节点 root 的二叉树，返回它 最深的叶节点的最近公共祖先 。

回想一下：

叶节点 是二叉树中没有子节点的节点
树的根节点的 深度 为 0，如果某一节点的深度为 d，那它的子节点的深度就是 d+1
如果我们假定 A 是一组节点 S 的 最近公共祖先，S 中的每个节点都在以 A 为根节点的子树中，且 A 的深度达到此条件下可能的最大值。
 

示例 1：


输入：root = [3,5,1,6,2,0,8,null,null,7,4]
输出：[2,7,4]
解释：我们返回值为 2 的节点，在图中用黄色标记。
在图中用蓝色标记的是树的最深的节点。
注意，节点 6、0 和 8 也是叶节点，但是它们的深度是 2 ，而节点 7 和 4 的深度是 3 。
示例 2：

输入：root = [1]
输出：[1]
解释：根节点是树中最深的节点，它是它本身的最近公共祖先。
示例 3：

输入：root = [0,1,3,null,2]
输出：[2]
解释：树中最深的叶节点是 2 ，最近公共祖先是它自己。
 

提示：

树中的节点数将在 [1, 1000] 的范围内。
0 <= Node.val <= 1000
每个节点的值都是 独一无二 的。
 
*/

// 定义结构体
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
right(right) {}
};

// 法一
/* 非lambda */
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
	public:
	// 非lambda
	struct Ans {
		int depth;
		TreeNode* lca;
		Ans(int d, TreeNode* node) : depth(d), lca(node) {}
	};

	Ans dfs(TreeNode* node) {
		if (!node) return Ans(0, nullptr);
		
		Ans left = dfs(node->left);
		Ans right = dfs(node->right);
		
		// 当前子树的最大深度 = 左右子树最大深度 +1
		int max_depth = max(left.depth, right.depth) + 1;
		
		if (left.depth == right.depth) {
			return Ans(max_depth, node); // 当前节点是LCA
		} else if (left.depth > right.depth) {
			return Ans(max_depth, left.lca); // 左子树的LCA传递
		} else {
			return Ans(max_depth, right.lca); // 右子树的LCA传递
		}
	}

	TreeNode* lcaDeepestLeaves(TreeNode* root) {
		return dfs(root).lca;
	}
};

// 法二
/**
 *  lambda 
 *	直接内联 减少额外参数调用  运行性能更佳
 * */

class Solution {
	public:
	TreeNode* lcaDeepestLeaves(TreeNode* root) {
		// 深度

		// 辅助结构体
		struct Ans {
			int depth;
			TreeNode* lca;
		};

		// 可递归lambda
		function<Ans(TreeNode*)> dfs = [&](TreeNode* node) -> Ans {
			if (!node)      return {0, nullptr};
			// 递归 左右子树
			auto left = dfs(node->left);
			auto right = dfs(node->right);

			// 当前递归深度
			int max_depth = max(left.depth, right.depth) + 1;

			// LCA
			if (left.depth == right.depth)      return {max_depth, node};
			else        return left.depth > right.depth ? Ans{max_depth, left.lca} :  Ans{max_depth, right.lca};
		};
		
		return dfs(root).lca;
	}
};